﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Com.Itrus.Raapi;
using System.Security.Cryptography.X509Certificates;
using System.Security.Cryptography;
using Com.Itrus.Raapi.Info;
using System.Configuration;
using Newtonsoft.Json;

namespace RN.ERP.BLL
{
    public class BaseITrusRaBLL
    {
        public static string RaRenewCert(
            bool RAEntity,
            int Count,
            string CSR,
            string CSRSigned,
            string Cert,
            string CertSN)
        {
            string ACCOUNT_ORGUNIT;
            string ACCOUNT_ORGANIZATION;
            string RA_SERVICE_URL;
            //自动获取模式
            //apply.EntityType = true;
            if (RAEntity)
            {
                ACCOUNT_ORGANIZATION = "青岛福莱易通软件有限公司";
                ACCOUNT_ORGUNIT = "办公室（个人）";
                RA_SERVICE_URL = "ica://123.234.82.24:5502/version=3&characterEncoding=GBK";
            }
            else
            {
                ACCOUNT_ORGANIZATION = "青岛福莱易通软件有限公司";
                ACCOUNT_ORGUNIT = "办公室（企业）";
                RA_SERVICE_URL = "ica://123.234.82.24:5501/version=3&characterEncoding=GBK";
            }
            Com.Itrus.Raapi.Result.OperationResult operationResult = null;
            try
            {
                RaCertManager raCertManager = RaFactory.GetRaCertManager(ACCOUNT_ORGANIZATION, ACCOUNT_ORGUNIT);
                raCertManager.AddRaService(RA_SERVICE_URL);

                X509Certificate2 x509 = new X509Certificate2();
                try
                {
                    x509.Import(Convert.FromBase64String(Cert));
                }
                catch
                {
                    return null;
                }
                DateTime validTo = x509.NotAfter.Date;
                validTo = (validTo - DateTime.Today).Days > 60 ? validTo : ((DateTime.Today - validTo).Days >= 0 ? DateTime.Today.AddYears(1) : validTo.AddYears(1));
                var Validity = (validTo.Date - DateTime.Today).Days.ToString();

                if (Count == 1 || DateTime.Now > x509.NotAfter) // 原先为单证，发放新双证 或 已过期双证书更新。
                {
                    var subject = x509.Subject.Split(',');
                    var nameCN = subject.FirstOrDefault(m => m.Trim().StartsWith("CN=")).Trim();
                    var emailCN = subject.FirstOrDefault(m => m.Trim().StartsWith("E=")).Trim();
                    var surCN = (subject.FirstOrDefault(m => m.Trim().StartsWith("SN=")) ?? "").Trim();
                    var af1CN = subject.FirstOrDefault(m => m.Trim().StartsWith("L=")).Trim();
                    var vers = surCN.Split('*');
                    var ver = vers.Length == 1 ? 0 : int.Parse(vers[1]);

                    UserInfo userInfo = new UserInfo();

                    userInfo.UserName = nameCN.Substring(3, nameCN.Length - 3);

                    userInfo.UserEmail = emailCN.Substring(2, emailCN.Length - 2);

                    userInfo.UserCountry = "CN";
                    userInfo.UserState = "";
                    userInfo.UserSurName = string.IsNullOrEmpty(vers[0]) ? "*1" : (vers[0].Substring(3, vers[0].Length - 3) + "*" + (ver + 1));
                    userInfo.UserStreet = "";
                    userInfo.UserAdditionalField1 = af1CN.Substring(2, af1CN.Length - 2);
                    userInfo.UserAdditionalField2 = "S:" + getMd5Hash(userInfo.UserName + (userInfo.UserEmail.Split('@').Count() > 1 ? userInfo.UserEmail.Split('@')[1] : "")).ToUpper().Substring(0, 4);

                    userInfo.CertReqBuffer = CSR;

                    userInfo.CertReqChallenge = "itrusyes";

                    userInfo.CertReqOverrideValidity = Validity; //设置证书有效期，如果注释，则取证书模板默认有效期

                    // KMC
                    userInfo.CertKmcReq2 = "kmcReqVersion=20101209";

                    userInfo.KeyMode = "ENROLL"; //设置申请时产生私钥

                    operationResult = raCertManager.EnrollCert(userInfo);
                }
                else // 原先为双证，更新流程
                {
                    if (CertSN != null && !CertSN.Equals(""))
                    {
                        if (CertSN.StartsWith("00"))
                        {
                            CertSN = CertSN.Substring(2, CertSN.Length - 2).ToUpper();
                        }
                        else
                        {
                            CertSN = CertSN.ToUpper();
                        }
                    }
                    RenewInfo renewInfo = new RenewInfo();
                    renewInfo.OrigCertSerialNumber = CertSN;
                    renewInfo.OrigCert = Cert;
                    renewInfo.PkcsInformation = CSRSigned;
                    renewInfo.CertReqBuf = CSR;

                    Validity = ConfigurationManager.AppSettings["Validity"];
                    renewInfo.CertReqOverrideValidity = Validity;
                    //默认更新需要审批
                    renewInfo.RenewMode = "APPROVE"; //MANUAL, APPROVE, AA, PASSCODE
                    //renewInfo.setPasscodeEx("04030B040E033496");
                    operationResult = raCertManager.RenewCert(renewInfo);
                }
            }
            catch (Exception err)
            {
                return "$@|" + err.Message;
            }
            return JsonConvert.SerializeObject(operationResult);
        }

        #region getMd5Hash
        /// <summary>
        /// 取得 MD5
        /// </summary>
        /// <param name="input"></param>
        /// <returns></returns>
        public static string getMd5Hash(string input)
        {
            if (input == null || input == "") return "";
            MD5 md5Hasher = MD5.Create();
            byte[] data = md5Hasher.ComputeHash(Encoding.Default.GetBytes(input));
            StringBuilder sBuilder = new StringBuilder();
            for (int i = 0; i < data.Length; i++)
            {
                sBuilder.Append(data[i].ToString("x2"));
            }
            return sBuilder.ToString();
        }
        #endregion getMd5Hash
    }
}
